<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
  <meta charset="UTF-8">
  <title>告警监控</title>
  <th:block th:include="common/pub_head :: default"></th:block>
  <th:block th:include="common/pub_head :: layui"></th:block>
  <style>
    /*滚动条的宽度*/
    ::-webkit-scrollbar {
      width: 5px;
      height: 5px;
    }

    /*外层轨道。可以用display:none让其不显示，也可以添加背景图片，颜色改变显示效果*/
    ::-webkit-scrollbar-track {
      /*滚动条里面轨道*/
      box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
      background: #ededed;
      border-radius: 10px;
    }

    /*滚动条的设置*/
    ::-webkit-scrollbar-thumb {
      /*滚动条里面小方块*/
      border-radius: 10px;
      background-color: #aeb9c2;
      background-image: -webkit-linear-gradient(
          45deg,
          rgba(255, 255, 255, 0.2) 25%,
          transparent 25%,
          transparent 50%,
          rgba(255, 255, 255, 0.2) 50%,
          rgba(255, 255, 255, 0.2) 75%,
          transparent 75%,
          transparent
      );
    }

    ::-webkit-scrollbar-thumb:hover {
      background-color: skyblue;
    }
  </style>
  <style>
    .pc-card {
      position: relative;
      text-align: center;
      float: left;
      margin: 5px;
      padding-bottom: 5px;
      cursor: pointer;
      height: 220px;
    }

    .active {
      border-radius: 10px;
      background-color: #ddd;
      height: auto;
    }

    .pc-card img {
      height: 120px;
      width: 140px;
      -webkit-user-drag: none;
    }

    .clear {
      clear: both;
    }

    .span-info {
      width: 150px;
    }

    .address {
      width: 150px;
      letter-spacing: 0;
      overflow: hidden;
      display: -webkit-box;
      text-overflow: ellipsis;
      -webkit-line-clamp: 2; /*要显示的行数*/
      -webkit-box-orient: vertical;
    }

    .remark {
      width: 150px;
      letter-spacing: 0;
      overflow: hidden;
      display: -webkit-box;
      text-overflow: ellipsis;
      -webkit-line-clamp: 2; /*要显示的行数*/
      -webkit-box-orient: vertical;
    }

    .no-data {
      position: absolute;
      display: none;
      top: 150px;
      left: 50%;
      transform: translate(-50%, 0);
      font-size: 30px;
      font-weight: bold;
      text-align: center;
      color: #ddd;
    }

    .pc-card .shadow {
      width: 100%;
      height: 100%;
      position: absolute;
      left: 0;
      top: 0;
      z-index: 999;
      background-color: #000;
      opacity: 0.7;
      border-radius: 10px;
    }

    .shadow .warn-info {
      z-index: 9999;
      color: #fff;
      position: absolute;
      top: 43%;
      left: 50%;
      width: 130px;
      transform: translate(-50%, -50%);
    }


    .float-left {
      margin: 0 4px;
      float: left;
      line-height: 16px;
    }

    .square {
      width: 15px;
      height: 15px;
    }

    .all {
    }

    .online {
      background-color: #009688;
    }

    .online-font {
      color: #009688;
    }

    .offline {
      background-color: #393D49;
    }

    .offline-font {
      color: #393D49;
    }

    .warn {
      background-color: #FFB800;
    }

    .warn-font {
      color: #FFB800;
    }

    .danger {
      background-color: #FF5722;
    }

    .danger-font {
      color: #FF5722;
    }

    .note {
      position: absolute;
      top: 11px;
      left: 68px;
    }

    .right-panel {
      position: fixed;
      right: 0;
      width: 20px;
      transition: width 2s;
      -moz-transition: width 1s; /* Firefox 4 */
      -webkit-transition: width 1s; /* Safari and Chrome */
      -o-transition: width 1s; /* Opera */
      z-index: 999999999;
    }

    .forward {
      position: relative;
      top: 0;
      cursor: pointer;
      float: left;
      background-color: #f2f2f2;
      line-height: 50px;
      height: 50px;
      border-radius: 50% 0 0 50%;
    }

    .layui-card {
      margin: 10px 10px 10px 10px;
      width: 270px;
      border: 1px solid #ddd;
      border-radius: 3%;
    }

    .layui-card:last-child {
      margin-bottom: 20px;
    }

    .pc-panel {
      position: absolute;
      left: 20px;
      height: 100%;
      width: 300px;
      background-color: #f2f2f2;
    }

    .pc-tab {
      overflow: auto;
    }

    .warn-btn {
      text-align: right;
    }

    .pc-content {
      text-align: center;
      padding: 0 25px;
      margin-top: 10px;
    }

    .pc-width {
      width: -webkit-calc(100% - 340px);
      width: -moz-calc(100% - 340px);
      width: calc(100% - 340px);
    }

    .page {
      position: fixed;
      bottom: 0;
      left: 50%;
      transform: translate(-50%, 0);
    }

    #pcDiv {
      border: 1px solid #ddd;
      overflow: auto;
      border-radius: 10px;
    }

    .status-div {
      margin-top: 5px;
      width: auto;
    }

    .status {
      padding: 4px 5px;
      border: 1px solid #ddd;
      border-radius: 5px;
      width: auto;
      float: left;
      margin-right: 5px;
    }

    .active {
      background-color: #21bac5;
      color: #fff;
    }

    .status:hover {
      cursor: pointer;
      background-color: #21bac5;
    }
  </style>
</head>
<body class="container" style="padding: 4px 5px">
<div class="right-panel">
  <div class="forward" style="padding-left: 5px">
    <i class="layui-icon layui-icon-prev"></i>
  </div>
  <div class="pc-panel">
    <blockquote class="layui-elem-quote"
                style="color: #FF5722;font-weight: bold;margin-bottom: 0">警报主机
    </blockquote>
    <div class="pc-tab">

    </div>
  </div>
  <div class="clear"></div>
</div>
<blockquote class="layui-elem-quote">电脑告警监控</blockquote>
<div class="layui-inline note" style="margin-right: 0">
  <label class="layui-form-label">状态</label>
  <div class="layui-input-inline status-div">
    <div class="status active" data-status="ALL">
      <span class="float-left ">全部【<span id="ALL">0</span>】</span>
      <div class="clear"></div>
    </div>
    <div class="status" data-status="ONLINE">
      <div class="square online float-left"></div>
      <span class="float-left ">在线【<span id="ONLINE">0</span>】</span>
      <div class="clear"></div>
    </div>
    <div class="status" data-status="OFFLINE">
      <div class="square offline float-left"></div>
      <span class="float-left">离线【<span id="OFFLINE">0</span>】</span>
      <div class="clear"></div>
    </div>
    <div class="status" data-status="WARN">
      <div class="square float-left warn"></div>
      <div class="float-left">异常【<span id="WARN">0</span>】</div>
      <div class="clear"></div>
    </div>
    <div class="status" data-status="DANGER">
      <div class="square float-left danger"></div>
      <div class="float-left">警报【<span id="DANGER">0</span>】</div>
      <div class="clear"></div>
    </div>
    <div class="clear"></div>
  </div>
</div>
<div class="layui-form-item">
  <div class="layui-inline">
    <label class="layui-form-label">电脑信息</label>
    <div class="layui-input-inline">
      <input type="text" name="content" id="content" autocomplete="off" class="layui-input"
             placeholder="请输入电脑信息">
    </div>
  </div>
  <div class="layui-inline">
    <a class="layui-btn layui-btn-sm layui-btn-warm" onclick="listBindAlarm()">微信告警人</a>
    <a class="layui-btn layui-btn-sm" onclick="pagePc()">查询</a>
    <a class="layui-btn layui-btn-primary layui-btn-sm"
       onclick="$('#content').val('');$('.status').eq(0).click()">重置</a>
  </div>
</div>
<div class="pc-content">
  <div class="no-data">没有数据...</div>
  <div id="pcDiv"></div>
  <div class="clear"></div>
</div>

<div id="pcPage" class="page"></div>

<div id="pcModel" style="display: none">
  <div class="pc-card">
    <div class="shadow">
      <div class="warn-info"></div>
    </div>
    <img class="img">
    <br/>
    <div class="span-info">
      <div class="ip"></div>
      <div class="address"></div>
      <div class="remark"></div>
    </div>
  </div>
</div>
<div id="dangerCardModel" style="display: none">
  <div class="layui-card">
    <div class="layui-card-header header">192.168.99.1</div>
    <div class="layui-card-body">
      <div>
        地址：<span class="card-address">综合楼4楼#301科室</span>
      </div>
      <div>
        备注：<span class="card-remark">用来玩耍的</span>
      </div>
      <div class="warn-btn">
        <a class="layui-btn layui-btn-xs layui-btn-primary"
           onclick="handleAlarm(this, 'FALSE_ALARM')">误告警</a>
        <a class="layui-btn layui-btn-xs layui-btn-danger"
           onclick="handleAlarm(this, 'POLICE')">出警</a>
      </div>
    </div>
  </div>
</div>
<script th:inline="javascript">
  //连接对象.
  var form;
  var laypage;
  layui.use(['table', 'form', 'laypage'], function () {
    form = layui.form;
    laypage = layui.laypage;
    createWebSocket();
  });
  var ws = null;

  var wxUrl = "ws://" + [[${serverDomain}]] + "/websocket/police";

  function createWebSocket() {
    layer.load(2, {
      content: '连接服务器中...',
      success: function (layero) {
        layero.find('.layui-layer-content').css({
          'paddingTop': '40px',
          'text-align': 'center',
          'width': '200px',
          'backgroundPositionX': 'center'
        });
      }
    });
    try {
      //判断当前的浏览器是否支持websocket.
      if ("WebSocket" in window) {
        ws = new WebSocket(wxUrl);
        init();
      } else {
        alert("Not support websocket");
        return false;
      }
    } catch (e) {
      console.log('catch');
      reconnect(wxUrl);
    }
  }

  var lockReconnect = false;
  var tt;

  function reconnect() {
    if (lockReconnect) {
      return;
    }
    lockReconnect = true;
    //没连接上会一直重连，设置延迟避免请求过多
    tt && clearTimeout(tt);
    tt = setTimeout(function () {
      createWebSocket();
      lockReconnect = false;
    }, 5000);
  }

  function init() {
    //连接成功的方法.
    ws.onopen = function (event) {
      layer.closeAll();
      console.log("Loc MSG:连接成功");
      //心跳检测重置
      pagePc();
      listDangerPc();
      heartCheck.start();
    };

    //连接关闭.
    ws.onclose = function (event) {
      console.log("Loc MSG:连接关闭");
      reconnect();
    };

    //连接异常.
    ws.onerror = function (event) {
      console.log("Loc MSG:连接异常");
      reconnect();
    };

    ws.onmessage = function (event) {
      var messageVo = JSON.parse(event.data);

      if (messageVo.cmdEnum == "REFRESH_ALL" || messageVo.cmdEnum == "DANGER") {
        // 刷新所有在线数据
        console.log("刷新所有");
        pagePc();
        listDangerPc();
      } else {
        console.log("接收消息：" + messageVo);
      }
      // 拿到任何消息都说明当前连接是正常的
      heartCheck.start();
    };
  }

  var listenerCount = 0;
  //心跳检测
  var heartCheck = {
    timeout: 3000, // 每隔三秒发送心跳
    severTimeout: 5000,  // 服务端超时时间
    num: 5,  // 5次心跳均未响应重连
    timeoutObj: null,
    start: function () {
      var _this = this;
      var _num = this.num;
      this.timeoutObj && clearInterval(this.timeoutObj);
      _this.timeoutObj = setInterval(function () {
        //这里发送一个心跳，后端收到后，返回一个心跳消息，
        //onmessage拿到返回的心跳就说明连接正常
        _num--;
        //计算答复的超时次数
        if (_num == 0) {
          ws.close();
        } else if (_num > 0) {
          listenerCount++;
          listenerCount = listenerCount % 60;
          ws.send(JSON.stringify({
            "listenerCount": listenerCount + ""
          })); // 心跳包
        }

      }, this.timeout);
    }
  }
</script>
<script th:inline="javascript">
  /*<![CDATA[*/
  jQuery(function () {
    $(".right-panel").height($(document).height() - 10);
    $(".pc-tab").height($(document).height() - 60);
    $(".forward").offset({
      top: $(document).height() / 2 - 30
    });

    $("#pcDiv").height($(document).height() - 165);
  });

  $(document).on("click", ".status", function () {
    $(".status").removeClass("active");
    $(this).addClass("active");

    pagePc()
  })

  function listBindAlarm() {
    var URL = path + "/alarm/listBindAlarm";

    layer.open({
      title: "微信告警人列表",
      type: 2,
      area: ['800px', '570px'],
      content: URL
    });
  }

  $(document).on("click", ".forward", function () {
    var width = $(".right-panel").width();
    if (width > 23) {
      $(this).find("i").attr("class", "layui-icon layui-icon-prev");
      $(".right-panel").width(23);
      $(".pc-content").removeClass("pc-width");
    } else {
      $(".right-panel").width(320);
      $(this).find("i").attr("class", "layui-icon layui-icon-next");
      $(".pc-content").addClass("pc-width");
    }
  });

  var imgList = {
    ONLINE: path + "/img/pc_online.png",
    OFFLINE: path + "/img/pc_offline.png",
    WARN: path + "/img/pc_warn.png",
    DANGER: path + "/img/pc_danger.png"
  };
  var statsDicMap = [[${statsDicMap}]];
  var infoStatusMap = [[${infoStatusMap}]];

  var pn = 1;
  var pageSize = 15;
  var pcPage = {
    elem: 'pcPage'
    , count: 0 //数据总数
    , layout: ['count', 'prev', 'page', 'next', 'limit']
    , limit: pageSize
    , limits: [10, 15, 20, 30, 40, 50, 100, 200]
    , jump: function (obj) {

    }
  };

  function listDangerPc() {
    var URL = path + "/manage/listDangerPc";
    var formData = {};

    $.post(URL, formData, function (dangerPcList) {
      if (dangerPcList && dangerPcList.length > 0) {
        var domEle = "";
        for (var i = 0; i < dangerPcList.length; i++) {
          var dangerCardModel = $("#dangerCardModel").clone();
          var pcBean = dangerPcList[i];

          dangerCardModel.find(".layui-card").addClass("danger-" + pcBean.mac);
          dangerCardModel.find(".header").html(pcBean.ip + " - " + new Date(pcBean.updateTime).format("yyyy-MM-dd HH:mm"));
          dangerCardModel.find(".card-address").html(pcBean.address + "123");
          dangerCardModel.find(".card-remark").html(pcBean.remark);
          dangerCardModel.find(".warn-btn").attr("data-mac", pcBean.mac);

          domEle += dangerCardModel.html();
        }

        $(".pc-tab").html(domEle);

        $(".right-panel").width(320);
        $(".forward").find("i").attr("class", "layui-icon layui-icon-next");
        $(".pc-content").addClass("pc-width");
      }
    }, "json");
  }

  function pagePc() {
    var status = $(".status").filter(function () {
      return $(this).hasClass("active")
    }).attr("data-status");

    var URL = path + "/manage/pagePc";
    var formData = {
      pn: pn,
      pageSize: pageSize,
      status: status,
      content: $("#content").val()
    };

    var load = layer.load();
    $.post(URL, formData, function (jsonData) {
      layer.closeAll();
      pcPage.curr = pn;
      pcPage.count = jsonData.count;
      pcPage.jump = function (obj, first) {
        if (first) {
          renderPcPage(jsonData);
        } else {
          formData = {
            pn: obj.curr,
            pageSize: obj.limit
          };
          load = layer.load();
          $.post(URL, formData, function (jsonData) {
            layer.close(load);
            renderPcPage(jsonData);
          }, "json");
        }
      };
      laypage.render(pcPage);
    }, "json");
  }

  function renderPcPage(jsonData) {
    var pcBeanList = jsonData.list;
    $("#ALL").html(jsonData.total);
    var domEle = "";
    if (pcBeanList) {
      var dangerFlag = false;
      if (pcBeanList && pcBeanList.length > 0) {
        for (var i = 0; i < pcBeanList.length; i++) {
          var pcBean = pcBeanList[i];
          var pcModel = $("#pcModel").clone();
          pcModel.find(".pc-card").addClass("mac-" + pcBean.mac);
          pcModel.find(".pc-card").attr("data-mac", pcBean.mac);
          pcModel.find(".pc-card").attr("data-ip", pcBean.ip);
          pcModel.find(".pc-card").attr("data-realIp", pcBean.realIp);
          pcModel.find(".pc-card").attr("data-address", pcBean.address);
          pcModel.find(".pc-card").attr("data-remark", pcBean.remark);
          pcModel.find(".pc-card").attr("data-status", pcBean.status);

          if (pcBean.infoStatus == "UN_COMPLETE" || pcBean.infoStatus == "INFO_CONFLICT") {
            pcModel.find(".warn-info").html(infoStatusMap[pcBean.infoStatus]);
            pcModel.find(".shadow").show();
            pcModel.find(".warn-info").show();
          } else {
            pcModel.find(".shadow").hide();
            pcModel.find(".warn-info").hide();
          }

          pcModel.find(".img").attr("src", imgList[pcBean.status]);
          pcModel.find(".ip").html(pcBean.ip);
          pcModel.find(".address").html(pcBean.address);
          pcModel.find(".remark").html(pcBean.remark);

          domEle += pcModel.html();
        }
        $(".no-data").hide();
      } else {
        $(".no-data").show();
      }
    }

    $("#pcDiv").html(domEle);
    if (domEle == "") {
      $(".no-data").show();
    } else {
      $(".no-data").hide();
    }

    calcPc();
  }

  function calcPc() {
    var URL = path + "/manage/calcPc";
    var formData = {};
    $.post(URL, formData, function (jsonData) {
      if (jsonData.flag) {
        $.each(jsonData.calcPc, function (key, val) {
          $("#" + key).html(val);
        })
      } else {
        layer.msg("统计错误，错误原因：" + jsonData.errorMsg, {icon: 2});
      }
    });
  }

  function handleAlarm(thisObj, type) {
    var txt = "确定是误告警吗?";
    if (type == "POLICE") {
      txt = "确定已出警吗?";
    }
    layer.confirm(txt, function () {
      var mac = $(thisObj).parent().attr("data-mac");

      var URL = path + "/manage/handleAlarm";
      var formData = {
        mac: mac,
        type: type
      };

      $.post(URL, formData, function (jsonData) {
        if (jsonData.flag) {
          layer.msg("操作成功", {icon: 1});
          $(thisObj).parents(".layui-card").remove();
          pagePc();
        } else {
          layer.msg("操作失败，错误原因：" + jsonData.errorMsg, {icon: 2});
        }
      })
    });
  }

  /*]]>*/
</script>
<script>
  /*<![CDATA[*/
  var subtips;

  function openMsg(thisObj) {
    var width = 250;
    var mac = $(thisObj).attr("data-mac");
    var ip = $(thisObj).attr("data-ip");
    var realIp = $(thisObj).attr("data-realIp");
    var address = $(thisObj).attr("data-address") ? $(thisObj).attr("data-address") : '未填写';
    var remark = $(thisObj).attr("data-remark") ? $(thisObj).attr("data-remark") : '未填写';
    var content = "<div style='width: " + width + "px; height: auto'>";
    content += "　mac：" + mac + "<br/>";
    content += "　　IP：" + ip + "<br/>";
    content += "连接IP：" + realIp + "<br/>";
    content += "　地址：" + address + "<br/>";
    content += "　备注：" + remark;
    content += "</div>";

    subtips = layer.tips(content, thisObj, {
      tips: 2,
      area: ['auto', 'auto'],
      time: 0
    });
  }

  $(document).on("mouseenter", ".pc-card", function () {
    openMsg(this);
  });
  $(document).on("mouseleave", ".pc-card", function () {
    layer.close(subtips);
  });

  document.onkeydown = EnterLogin;

  function EnterLogin(event) {
    if (event.keyCode == 13) {
      if ($(".active").length > 0 && $(".layui-layer-iframe").length == 0) {
        $(".active").dblclick();
      }
    } else if (event.keyCode == 37) {
      if ($(".active").length == 0) {
        $(".pc-card").eq(0).click();
      } else {
        var index = $(".active").attr("data-index");
        if (index > 0) {
          $(".pc-card").eq(parseInt(index) - 1).click();
        }
      }
      return false;
    } else if (event.keyCode == 38) {
      if ($(".active").length == 0) {
        $(".pc-card").eq(0).click();
      } else {
        var index = $(".active").attr("data-index");
        var width = $(".active").width() + 50;
        var dWidth = $(document).width();
        var col = parseInt(dWidth / width);
        if (index >= col) {
          $(".pc-card").eq(parseInt(index) - col).click();
        }
      }
      return false;
    } else if (event.keyCode == 39) {
      if ($(".active").length == 0) {
        $(".pc-card").eq(0).click();
      } else {
        var length = $(".pc-card").length;
        var index = $(".active").attr("data-index");
        if (length - index > 0) {
          $(".pc-card").eq(parseInt(index) + 1).click();
        }
      }
      return false;
    } else if (event.keyCode == 40) {
      if ($(".active").length == 0) {
        $(".pc-card").eq(0).click();
      } else {
        var length = $(".pc-card").length;
        var index = $(".active").attr("data-index");
        var width = $(".active").width() + 50;
        var dWidth = $(document).width();
        var col = parseInt(dWidth / width);
        if (length - index > col) {
          $(".pc-card").eq(parseInt(index) + col).click();
        }
      }
      return false;
    }
  }

  $(document).on("click", ".pc-card", function () {
    $(".pc-card").removeClass("active");
    $(this).addClass("active");
  });

  $(document).on("dblclick", ".pc-card", function () {
    var mac = $(this).attr("data-mac");
    var status = $(this).attr("data-status");
    fillInfo(mac, status);
  });

  function fillInfo(mac, status) {
    var URL = path + "/pc/fillInfo/" + mac;

    var clzzArr = {
      "ONLINE": '',
      "OFFLINE": 'layui-btn-primary',
      "WARN": 'layui-btn-warm',
      "DANGER": 'layui-btn-danger'
    };
    var title = "查看电脑信息　-　主机状态：<a class='layui-btn layui-btn-xs " + clzzArr[status] + "'>" + statsDicMap[status] + "</a>"

    layer.open({
      title: title,
      type: 2,
      area: ['800px', '450px'],
      content: URL
    });
  }

  /*]]>*/
</script>
</body>
</html>